package com.situ.storehouse.util;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alibaba.fastjson2.JSON;

public class BaseController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//从请求中接受一个参数
		String action=request.getParameter("action");
		//根据参数决定要做哪一个事件
		//通过反射获取当前类中所有的方法
		Method[] methods=this.getClass().getDeclaredMethods();
		//遍历方法数组，找到要找的那个方法
		Method method=null;
		for(Method m:methods) {
			if(m.getName().equals(action)) {
				method=m;
			}
		}
		invokeController(method,request,response);

	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	//获取一个方法，用反射机制来执行这个方法
	private void invokeController(Method method,HttpServletRequest request, HttpServletResponse response) {
		try {//获取方法中参数列表
			Parameter[] parameters=method.getParameters();
			
			//获取方法中所有参数类型
			Class<?>[] types=method.getParameterTypes();
			
			//创建一个数组长度为原方法参数个数的数组
			Object[] params=new Object[types.length];
			
			//循环判断，根据方法中参数的类型传入对应的参数 一个或者两个
			for(int i=0;i<types.length;i++) {
				//获取当次循环对应的那个参数
				Parameter p=parameters[i];
				
				//注意配合Eclipse 中的设置： windows-Java-Complier中store information about method parameter使用
				
				//获取参数名
				String pName=p.getName();
				
				if(types[i].equals(HttpServletRequest.class)) {
					params[i]=request;
				}else if(types[i].equals(HttpServletResponse.class)) {
					params[i]=response;
				}
				else if(types[i].equals(String.class)) {
					params[i]=request.getParameter(pName);
				}
				else if(types[i].equals(BigDecimal.class)) {
					String value=request.getParameter(pName);
					if(value!=null && !"".equals(value)) {
						params[i]=new BigDecimal(value);
					}
				}
				else if(types[i].equals(HttpSession.class)) {
					params[i]=request.getSession();
				}
				else if(types[i].equals(Date.class)) {
					String value=request.getParameter(pName);
					if(value!=null && !"".equals(value)) {
					SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
					params[i]=sdf.parse(value);
					}
				}
				else if(types[i].equals(Double.class)) {					
					String value=request.getParameter(pName);
					if(value!=null && !"".equals(value)) {
						params[i]=Double.parseDouble(value);
					}
				}//判断一下，如果传入参数的类型是Integer类型，就根据参数名将请求中对应的参数值取出来，然后转为Integer类型，放入参数列表
				else if(types[i].equals(Integer.class)) {
						String value=request.getParameter(pName);
						if(value!=null && !"".equals(value)) {
							params[i]=Integer.parseInt(value);
						}
					}else {//如果以上类型都不是，则认为是自定义的类型
						params[i]=makeObject(request,types[i]);
						
					}
				
					
				
			}
			Object result=method.invoke(this,params);
			if(result!=null) {
				response.setContentType("application/json;charset=UTF-8");
				response.getWriter().write(JSON.toJSONString(result));
			}
			
		} catch (Exception e) {
			
		}
	}
	//接受请求对象和一个具体的类型
	public Object makeObject(HttpServletRequest request,Class<?> type) {
		try {
			Object o=type.newInstance();
			Enumeration<String> names=request.getParameterNames();//获取请求参数的名字
			//循环枚举所有的名字，返回false代表没有下一个了
			while(names.hasMoreElements()) {
				//获取出当前这次循环的参数的名字
				String name=names.nextElement();
				String value=request.getParameter(name);//此参数的值
				try {
					Field f=type.getDeclaredField(name);//获取当前这个type类的name属性
					f.setAccessible(true);
					if(f.getType().equals(String.class)) {
						f.set(o, value);
					}else if(f.getType().equals(Integer.class)) {
						if(value!=null && !"".equals(value)) {
							f.set(o, Integer.parseInt(value));
						}	
					}else if(f.getType().equals(BigDecimal.class)) {
						if(value!=null && !"".equals(value)) {
							f.set(o,new BigDecimal(value));
						}	
					}
					else if(f.getType().equals(Date.class)) {
						if(value!=null && !"".equals(value)) {
						SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
							f.set(o,sdf.parse(value));
						}	
					}
					
					
				}catch(Exception e) {
					
				}
			}
			return o;
		} catch (Exception e) {
			return null;
		} 
	}
	
}
